﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////

#pragma once

#include "YccCollaborationInterface.h"
#include <unordered_map>
#include "Any.h"

namespace gcmp
{
    class IDocument;
    class IDataset;
}

namespace gap
{
    enum class EnLevelTag;

    enum class ConfigType
    {
        SpaceConfig,
        GridConfig,
        BuildingItem,
        BuildingItemElevationSet,
        BuildingItemAxisGrid,
        BuildingItemCoordinate,
        GstGridConfig // 结构辅助轴线
    };

    /// 权限类型
    enum class EProjectPermission
    {
        UNKNOWN,   ///< 未知类型
        READ,      ///< 读
        WRITE,     ///< 写
        SOFTWRITE  ///< 读写
    };

    struct HttpMessage {
        int Code; // 错误码，解释可查看Message，如30005代表版本过期，54104代表数据被使用无法删除（如子项被工作单元绑定无法删除）
        std::wstring Message; // 错误码错误解释
    };

    struct YCC_COLLABORATION_INTERFACE_EXPORT ProjectItemConfig
    {
        ConfigType ProjectConfigType = ConfigType::BuildingItem;
        std::wstring BuildingItemId;
        int Version = -1;
        std::wstring BirthTime;
        std::wstring UpdateTime;
        std::wstring ProjectConfigData;
        int Revision = 0;
        std::wstring Major;
        std::wstring Tag;
    };

    struct YCC_COLLABORATION_INTERFACE_EXPORT UpdateConfig {
        ConfigType ProjectConfigType = ConfigType::BuildingItem;
        std::wstring ProjectConfigData;
        int Version = -1;
    };

    struct YCC_COLLABORATION_INTERFACE_EXPORT ElevationConfig {
        std::wstring ConfigData;
        std::wstring Tag;
        ElevationConfig(std::wstring configData,std::wstring tag):ConfigData(configData),Tag(tag){}
    };

    struct ProjectInformation
    {
        std::wstring ProjectName;// 项目名称
        std::unordered_map<std::wstring, gcmp::Any> Properties; // <标准编码,值>
    };

    class YCC_COLLABORATION_INTERFACE_EXPORT IProjectConfigManager
    {
    public:
        virtual ~IProjectConfigManager() {};

        static IProjectConfigManager* Get(const gcmp::IDocument* pDoc);

        static std::wstring GetTagWStringByLevelTag(const gap::EnLevelTag tag);

        static gap::EnLevelTag GetLevelTagByTagWString(const std::wstring& tagStr);
        
        virtual std::wstring GetProjectId() const = 0;

        virtual bool GetLatestBuildingItems(std::vector<gap::ProjectItemConfig>& buildingItems, int& latestConfigVersion) const = 0;

        virtual bool GetLatestProjectItemConfig(gap::ProjectItemConfig& latestProjectItemConfig, const std::wstring& buildingItemId, gap::ConfigType configType) const = 0;

        virtual bool GetBuildingItemIdsByWorkUnitId(std::vector<std::wstring>& buildingItemIds, const std::wstring& workUnitId) const = 0;

        virtual bool GetDatasetIdsByBuildingItemId(const std::wstring& buildingId, std::vector<std::wstring>& datasetIds) const = 0;

        virtual bool UpdateProjectItemConfig(const std::wstring& buildingItemId, gap::ConfigType configType, int version, const std::wstring& projectConfigData) = 0;

        virtual bool AssociateDatasetAndBuildingItem(const std::wstring& workUnitId, const std::wstring& buildingId) const = 0;

        virtual bool CreateProjectItemConfig(const std::wstring& buildingItemId, gap::ConfigType configType, const std::wstring& projectConfigData) = 0;
    
        virtual bool GetProjectItemConfig(gap::ProjectItemConfig& projectItemConfig, const std::wstring& buildingItemId, gap::ConfigType configType, int version) const = 0;

        virtual bool GetPermissionTypes(std::map<std::wstring, EProjectPermission>& permissions) const = 0;

        virtual bool AddBuildingItem(HttpMessage& httpMessage, std::wstring& buildingItemId, int configVersion, const std::wstring& buildingItemConfigData) const = 0;

        virtual bool UpdateBuildingItem(HttpMessage& httpMessage, int configVersion, const std::wstring& buildingItemId, const std::wstring& buildingItemConfigData) const = 0;

        virtual bool DeleteBuildingItem(HttpMessage& httpMessage, int configVersion, const std::wstring& buildingItemId) const = 0;

        virtual bool GetAllLatestBuildingItems(std::vector<std::pair<gap::ProjectItemConfig, int>>& buildingItems, std::vector<std::wstring>& subItemIds) const = 0;
        virtual bool GetAllLatestConfigByProjectId(std::vector<gap::ProjectItemConfig>& projectItemConfigs) const = 0;
        virtual bool CreateProjectItemConfigs(const std::wstring& subItemId, const std::map<gap::ConfigType, std::wstring>& configs) const = 0;
        virtual bool UpdateProjectItemConfigs(const std::wstring& subItemId, const std::vector<gap::UpdateConfig>& configs) const = 0;

        virtual bool CreateOrChangeMajorElevation(gap::HttpMessage& httpMessage, const std::wstring& subItemId, const std::wstring& configData, const std::wstring& major, const std::wstring& tag, std::vector<std::wstring>& conflictNames) const = 0;
        virtual bool GetMajorElevation(const std::wstring& subItemId, const std::wstring& major, const std::wstring& tag, gap::ProjectItemConfig& buildingItems) const = 0;
        virtual bool GetAllElevation(const std::wstring& subItemId, const std::wstring& major, std::vector<gap::ProjectItemConfig>& buildingItems) const = 0;
        virtual bool BatchConfigElevation(gap::HttpMessage& httpMessage, const std::vector<gap::ElevationConfig>& configs, const std::wstring& subItemId, const std::wstring& major, std::vector<std::wstring>& conflictNames) const = 0;

        virtual bool UpdateDatasetProjectItemConfig(gcmp::IDataset* pDataset, gcmp::IDocument* pDoc) const = 0;

        /// \brief 获取项目信息
        virtual bool GetCollaborationProjectInformation(ProjectInformation& projectInfomation) const;

        /// \brief 获取子项参数与项目信息
        virtual bool GetProjectInformationByBuildingItemId(const std::wstring& buildingId, ProjectInformation& projectInformation) const;

        /// \brief 上传自定义数据
        /// \param paths 类似于｛"GAP","IFC"｝
        /// \param data 保存数据
        /// \param version 返回的版本
        /// \return 成功 失败
        virtual bool UploadCustomData(const std::vector<std::wstring>& paths, const std::wstring& data, int& version) const;

        /// \brief 获取自定义数据
        /// \param paths 类似于｛"GAP","IFC"｝
        /// \param data 返回的数据
        /// \param version 返回的版本
        /// \return 成功 失败
        virtual bool GetCustomData(const std::vector<std::wstring>& paths, std::wstring& data, int& version) const;

        /// \brief 根据子项id获取最新的子项配置：如获取最新版本的子项，轴网、标高和坐标
        ///
        /// \param buildingItemId 子项id
        /// \param latestProjectItemConfigs 返回子项id下，最新的子项配置
        /// \return 返回是否获取成功
        virtual bool GetLatestProjectItemConfigsByBuildingItemId(const std::wstring& buildingItemId, std::vector<gap::ProjectItemConfig>& latestProjectItemConfigs) const;

        /// \brief 获取是否具有子项轴网标高的编辑权限
        /// \param buildingItemId 子项id
        /// \param isHasGridPermission 返回的数据是否具有轴网编辑权限
        /// \param isHasLevelPermission 返回的数据是否具有标高编辑权限
        /// \return 成功 失败
        virtual bool GetProjectItemConfigPermission(const std::wstring& buildingItemId, bool& isHasGridPermission, bool& isHasLevelPermission) const;
    };

    class YCC_COLLABORATION_INTERFACE_EXPORT IProjectConfigManagerFactory
    {
    public:
        virtual ~IProjectConfigManagerFactory() {};

        static IProjectConfigManagerFactory* Get();
        virtual IProjectConfigManager* CreateInstance(const gcmp::IDocument* pDoc) = 0;

    protected:
        static IProjectConfigManagerFactory* m_pFactory;
    };
}